<?php
namespace app\api\controller;
use app\admin\model\Bottle;
use app\api\cache\TokenCache;
use app\api\logic\LoginLogic;
use app\api\model\Management;
use app\api\model\OrderGoods;
use app\common\logic\OrderGoodsLogic;
use app\common\logic\OrderLogLogic;
use app\common\model\Client_;
use app\common\model\NoticeSetting;
use app\common\model\Order;
use app\common\model\OrderLog;
use app\common\model\Pay;
use app\common\server\ConfigServer;
use app\common\server\UrlServer;
use app\common\server\WeChatPayServer;
use app\common\server\WeChatServer;
use think\Db;
use think\Exception;
use think\facade\Config;
use think\facade\Hook;
use think\facade\Log;
use think\facade\Request;
use app\api\model\User;
use think\facade\Cache;

class FeiHong extends ApiBase
{
    public $like_not_need_login = ['getWeChatIphone','getWeChatToken','driverMes', 'login', 'sms', 'getBanner', 'goodsList', 'agreement', 'rent', 'aa','bookingNew'];

    public function login()
    {
        DB::startTrans();
        try{
            $data = Request::post();

            $result = $this->validate($data,'app\api\validate\FeiHong.login');
            if($result !== true){
                throw new Exception($result);
            }
            $mobile = $data['mobile']; //手机号
            $verifyCode = $data['verify_code']; //验证码
            $code = $data['code'] ?? ''; //微信code  用来获取微信userID
            //判断手机验证码是否一致
            Cache::set($mobile.'test9999', $verifyCode); //登录缓存手机验证码
            if ($verifyCode == 999999) {
                $smsCode = 999999; //测试专用

            }elseif($verifyCode == 888888) {
                $smsCode = 888888; //测试专用
            } else {
                $smsCode = Cache::get('sms_'.$mobile);
            }
            if ($verifyCode != $smsCode) {
                throw new Exception('手机验证码错误');
            }
            $expire_time = time() + Config::get('project.token_expire_time');
            $token = md5("feihong_".$mobile.$expire_time);
            //判断用户存不存在
            $user = $this->getUser($mobile);
            $ifOpen = 0; // 未开户
            if (!$user) {
                //不存在直接注册为新用户登录后提示未绑定用户
                $post = request()->post();
                $post['password'] = '';
                $post['client'] = Client_::mnp;
                $post['mobile'] = $mobile;
                $token = LoginLogic::register($post);
                $user = $this->getUser($mobile);  //重新查询用户数据
            } else {
                //已经存在用户，判断if_open是否开户，未开户的话登录后提示未绑定用户
                if ($user->status == 2) {
                    throw new Exception('用户已被禁用');
                }
                if ($user->if_open == 1) {
                    $ifOpen = 1;
                }
            }
            $row = Db::name('session')->where(['user_id' => $user->id, 'type' => 0])->find();
            $result = ['user_id' => $user->id, 'token' => $token, 'client' => 1, 'update_time' => time(), 'expire_time' =>$expire_time];
            if (!$row) {
                Db::name('session')->insert($result);
            } else {
                $row = $result;
                unset($row['user_id']);
                Db::name('session')->where(['user_id' => $user->id, 'type' => 0])->update($row);
            }
            $auth = Db::name('user_auth')->where(['user_id' => $user->id, 'type' => 0])->find();
            //获取用户的openId
            $getOpenArr = $this->getOpenId($code);

            $openid = $getOpenArr['openid'] ?? '';
            if (!$auth) {
                $dataArr['user_id'] = $user->id;
                $dataArr['openid'] = $openid;
                $dataArr['create_time'] = time();
                $dataArr['update_time'] = time();
                $dataArr['client'] = 1;  //微信小程序
                $dataArr['type'] = 0;  //微信小程序
                Db::name('user_auth')->insert($dataArr);
            } else {
                if ($openid) {
                    Db::name('user_auth')->where(['user_id' => $user->id, 'type' => 0])->update(['update_time' => time(), 'openid' => $openid]);
                }
            }
            $result['if_open'] = $ifOpen;
            $result['reg_time'] = $user->reg_time ?: '';
            Cache::rm('sms_'.$mobile);
            //该用户存在绑定小程序ID 待定
            Db::commit();
            $this->_success('登录成功', $result);
        }catch (Exception $e){
            DB::rollback();
            $this->_error($e->getMessage());
        }

    }

    //获取微信openid
    public function getOpenId($code)
    {
        $code = $code ?: $this->request->post('code');
        $config = WeChatServer::getOaConfig(); // 微信配置
        $appid = $config['user_app_id'];
//        $appid = 'wx45afad0e910405ad';
        $secret = $config['user_secret'];
//        $secret = 'cd1ac9f22a61bc95476f092c5acf48f0';
        $url = 'https://api.weixin.qq.com/sns/jscode2session?appid=' . $appid . '&secret=' . $secret . '&js_code=' . $code . '&grant_type=authorization_code';

        return $this->curl($url);
//        $data['openid'] = $obj["openid"];


    }

    public function curl($url)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        // To ensure communication security,all api use https,so need use two line code to open ssl safety check
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_URL, $url);

        $res = curl_exec($curl);
        $error = curl_error($curl);
        curl_close($curl);
        if ($error) {
            return $error;
        }

        return json_decode($res, true);
    }

    public function register()
    {
        Db::startTrans();
        try {
            $data = $this->getAddress();
            $mobile = $data['mobile'];
            unset($data['mobile']);
            //入库
            $model = (new User())->save($data, ['mobile' => $mobile]);
            if (!$model) {
                throw new Exception('注册失败');
            }
            Db::commit();
            $this->_success('注册成功');
        }catch (Exception $e) {
            $this->_error($e->getMessage());
            Db::rollback();
        }

    }
    /*
     * 手机验证码
     */
    public function sms()
    {
        try{
            $mobile = $this->request->post('mobile');
            $key = $this->request->post('key','ZCYZ');
            //发送手机验证码
            (new Sms())->send($mobile, $key);
        }catch (Exception $e) {
            $this->_error($e->getMessage());
        }

    }
    //首页横幅
    public function getBanner()
    {
        $position = $this->request->get('position', 1); //广告位置
        $data = Db::name('ad')->where(['client' => 1, 'pid' => $position,
            'status' => 1, 'del' => 0])->order('sort desc')->select();
        if (!$data) {
            $this->_error('不存在数据');
        }
        $this->_success('查询成功', $data);
    }
    //商品列表
    public function goodsList()
    {
        $type = $this->request->get('type', 0); //type = 1(主商品) 2（附属商品）
        $sel = $this->request->get('sel', 0); //sel = 1(新品推荐);2(好物优选);3(猜你喜欢);4(热销商品)
        $page = $this->request->get('page', 1); //页数
        $limit = $this->request->get('limit', 10); //条数
        $condition = '';
        $order = 'click_count desc';
        switch($sel) {
            case 1:
                $condition = "is_new = 1";
                break;
            case 2:
                $condition = "is_best = 1";
                break;
            case 3:
                $condition = "is_like = 1";
                break;
            case 4:
                $order = "sales_sum desc";
                break;
        }
        $where = '';
        if ($type) {
            $where = "type = {$type}";
        }
        $data = Db::name('goods')->where(['del' => 0, 'status' => 1])
            ->where($where)
            ->where($condition)->order($order)
            ->paginate(['list_rows' => $limit, 'page' => $page]);
        if (!$data) {
            $this->_error('不存在数据');
        }
        $this->_success('查询成功', $data);
    }
    //我的个人中心
    public function getUserList()
    {
        $token = $this->user_info['token'];
        return Db::name('user u')
            ->join('session s', 'u.id=s.user_id')
            ->where(['s.token' => $token])
            ->field('u.*,s.token,s.client')
            ->find();

    }

    //退出登录
    public function logout()
    {
        try {
            $userId = $this->user_info['id'];
            $token = $this->user_info['token'];
            $session = Db::name('session')->where(['user_id' => $userId, 'type' => 0])->update(['token' => '']);
            if (!$session) {
                throw new Exception('退出失败');
            }
            //登录缓存删除
            $token_cache = new TokenCache($token, ['token' => $token, 'type' => 0]);
            $token_cache->del();
            $this->_success('退出成功');
        }catch (Exception $e) {
            $this->_error($e->getMessage());
        }
    }

    //用户协议
    public function agreement()
    {
        $data = ConfigServer::get('policy', 'service');
        if ($data) {
            $this->_success('查询成功', $data);
        }
        $this->_error('无用户协议');
    }

    //修改地址
    public function address()
    {
        $user = $this->user_info;
        $user = User::where(['id' => $user['id']])->find();
        $address = $this->getAddress();
        $model = $user->save($address);
        if (!$model) {
            $this->_error('保存失败');
        }
        $this->_success('保存成功');

    }

    /**
     * 我的押瓶
     */
    public function bottle()
    {

        $type = $this->request->get('type', 1); //type 1（当前所押瓶） 2（缴租记录）
        $page = $this->request->get('page', 1); //页数
        $limit = $this->request->get('limit', 10); //条数
        $bottleDeposit = Db::name('user')->where(['id' => $this->user_info['id']])
            ->field('bottle_deposit, bottle_rent')->find();
        $bottleRent = $bottleDeposit['bottle_rent'] ?: $this->getConfig('pay','bottle_rent',''); //租金
        $bottle_deposit = $bottleDeposit['bottle_deposit'] ?: $this->getConfig('pay','bottle_deposit',''); //押金
        if ($type == 2) {
            $bottle = Db::name('bottle_rent_log')
                ->where(['user_id' => $this->user_info['id']])
                ->order('pay_time asc')
                ->paginate(['list_rows' => $limit, 'page' => $page])->each(function($item, $key){
                    $code = json_decode($item['bottle_code'], true);
                    $time ='';
                    if ($code) {
                        $code2 = [];
                        foreach ($code as $vv) {
                            $time = $vv['time'];
                            $code2[] = $vv['bottle_code'];
                        }
                        $item['intervals'] = $time;

                        $item['code'] = implode(',', $code2);

                        if(!$item['end_time']){
                            $item['end_time'] = '';
                        }
                        if($item['pay_time']==0){
                            $item['pay_time'] = '';
                        }
                    }
                    $item['num'] = count(json_decode($item['bottle_code'], true));
                    return $item;
                });

        } else {

            $bottleArr = Db::name('bottle')->alias('b')
                ->where(['b.user_id' => $this->user_info['id']])
                ->field('b.user_id, b.code bottle_code, b.createtime, b.updatetime, b.status,b.bottle_deposit')
                ->paginate(['list_rows' => $limit, 'page' => $page]);
            if($bottleArr){
                $bottle = $bottleArr->toArray();
            }

//            //钢瓶租金
//            $bottle_rent = $this->getConfig('pay', 'bottle_rent');
//            foreach($bottle['data'] as $index =>  $item){
//                //欠费金额=租金x天数
//                $bottle_rent_money=0;
//                $today = ceil((time()-strtotime($item['updatetime']))/86400);
//                $bottle_rent_money += $today*$bottle_rent;
//                $bottle['data'][$index]['bottle_rent_money'] = $bottle_rent_money;
//            }
            //钢瓶租金 如果用户设置了租金就按用户的走
            $user = \app\admin\model\User::where('id',$this->user_info['id'])->find();
            $bottle_rent = Db::name('config')->where(['type'=>'pay','name'=>'bottle_rent'])->value('value');
            $bottle_rent = (isset($user['bottle_rent']))?round($user['bottle_rent'],2):$bottle_rent;
            foreach($bottle['data'] as $index =>  $item){
                //欠费金额=租金x天数
                $bottle_rent_money=0;
                $today = ceil((time()-strtotime($item['updatetime']))/86400);
                $bottle_rent_money += $today*$bottle_rent;
                $bottle['data'][$index]['bottle_rent_money'] = sprintf("%.2f",$bottle_rent_money);
                //钢瓶押金 如果用户设置了押金就按用户的走
//                $bottle['data'][$index]['bottle_deposit'] = (isset($user['bottle_deposit']))?round($user['bottle_deposit'],2):$item['bottle_deposit'];
            }
        }

        $data = [];
        if ($bottle) {
            $data['bottle'] = $bottle;
            $data['bottle_deposit'] = $bottle_deposit; //押金
            $data['bottle_rent'] = $bottleRent; //租金
        }

        $this->_success('查询成功', $data);
    }

    //
    public function myBookSite()
    {
        $siteId = Db::name('user')->where(['id' => $this->user_info['id']])->value('site_id');
        $site = Db::name('bottle_site')->where(['id' => $siteId])->find();
        $data = [];
        if ($site) {
            $data['address'] = $site['address'];
            $data['siteMsg']['name'] = $site['name'];
            $data['siteMsg']['head_mobile'] = $site['head_mobile'];
            $data['siteMsg']['latitude'] = $site['latitude'];
        }

        $this->_success('查询成功', $data);

    }

    //我要订气列表
    public function bookingList()
    {
        //获取购物车cache下的商品
        $user = $this->user_info;
        $orderList = Cache::get($user['id']);
        if ($orderList) {
            $this->_success('查询成功', json_decode($orderList, true));
        } else {
            $this->_error('无数据');
        }

    }

    //回收折价说明
    public function showMsg()
    {
        $data['discount'] = ConfigServer::get('pay', 'discount');
        $data['rent'] = ConfigServer::get('pay', 'rent');
        $data['return'] = ConfigServer::get('pay', 'bottle_return');
        $this->_success('查询成功', $data);
    }

    //配置表信息
    public function showConfig()
    {
        $type = $this->request->get('type');
        $name = $this->request->get('name');
        $data = $this->getConfig($type, $name);
        $this->_success('查询成功',$data );
    }

    //清空购物车
    public function clearCart()
    {
        Cache::rm($this->user_info['id']);
        $this->_success('清空购物车成功');
    }

    //下单
    public function booking()
    {
        $goodsId = $this->request->post('goods_id'); //商品ID
        $calc = $this->request->post('calc'); //add+1 或者 reduce-1
        $displaceOrAdd = $this->request->post('displace_or_add', ''); //押瓶置换 新增押瓶
        $user = $this->user_info;
        $address = Db::name('user')->where(['id' => $user['id']])->field('address, bottle_num')->find();
        if (empty($address['address'])) {
            $this->_error('请先完善收货信息');
        }

        $data['goods_id'] = $goodsId;
        $result = $this->validate($data,'app\api\validate\FeiHong.booking');
        if($result !== true){
            $this->_error($result);
        }
        $goods = \app\api\model\Goods::where(['id' => $goodsId])->find(); //商品信息
        if (!$goods) {
            $this->_error('不存在的商品');
        }
        $arr = [];
        //保存下单商品到缓存
        $key = $user['id'];
        if (Cache::has($key)) {
            //同个用户下存在重复下单的商品 +1 价格也加
            $goodsCache = Cache::get($key);
            $arr = json_decode($goodsCache, true);
            $id = array_column($arr, 'id');
            foreach($arr as $k => $v) {

                if ($v['type'] == 1) {
                    if ($displaceOrAdd == 1) {
                        if ($address['bottle_num'] < $v['num']) {
                            $this->_error("您当前可用共享瓶数为{$address['bottle_num']}个，请新增共享瓶");
                        }
                    }
                }
                //重复的商品订单加1
                if ($v['id'] == $goodsId) {
                    if ($calc == 'reduce') {
                        $arr[$k]['num'] -= 1;
                        $arr[$k]['price'] = bcsub( $arr[$k]['price'], $goods['price'], 2);
                    } else {
                        //默认下单跟加1，都是这个
                        $arr[$k]['num'] += 1;
                        $arr[$k]['price'] = bcadd( $arr[$k]['price'], $goods['price'], 2);
                    }
                    break;
                } else {
                    if (!in_array($goodsId, $id)) {
                        $goods['num'] = 1;
                        array_unshift($arr, $goods);
                        break;
                    }
                }
            }
        } else {
            $goods['num'] = 1;
            $arr[] = $goods;
        }
        Cache::set($key, json_encode($arr, 256));
        $this->_success('下单成功', $arr);
    }
    //下单
    public function bookingNew()
    {
        $goodsId = $this->request->post('goods_id'); //商品ID
        $calc = $this->request->post('calc'); //add+1 或者 reduce-1
        $num = $this->request->post('num',1);
        $displaceOrAdd = $this->request->post('displace_or_add', ''); //押瓶置换 新增押瓶
        $user = $this->user_info;
        $address = Db::name('user')->where(['id' => $user['id']])->field('address, bottle_num')->find();
        if (empty($address['address'])) {
            $this->_error('请先完善收货信息');
        }

        $data['goods_id'] = $goodsId;
        $result = $this->validate($data,'app\api\validate\FeiHong.booking');
        if($result !== true){
            $this->_error($result);
        }
        $goods = \app\api\model\Goods::where(['id' => $goodsId])->find(); //商品信息
        if (!$goods) {
            $this->_error('不存在的商品');
        }
        $arr = [];
        //保存下单商品到缓存
        $key = $user['id'];
        $goods['num'] = $num;
        $arr[] = $goods;
        Cache::set($key, json_encode($arr, 256));
        $this->_success('下单成功', $arr);
    }

    //我的订单
    public function myOrder()
    {
        //order order_goods order_status订单状态;0-待付款;1-待发货;3-已完成;
        $orderStatus = $this->request->get('order_status', -1);
        $where = "order_status = {$orderStatus}";
        if ($orderStatus == -1) {
            $where = "";
        }
        $userId = $this->user_info['id'];
        $page = $this->request->get('page', 1); //页数
        $limit = $this->request->get('limit', 10); //条数

        $orderResult = \app\api\model\Order::where(['user_id' => $userId, 'del' => 0])->where($where)
            ->field('order_sn, id, order_amount, create_time')
            ->order('create_time desc')
            ->paginate(['list_rows' => $limit, 'page' => $page]);

        $order = $orderResult->toArray();
        $orderIds = array_column($order['data'], 'id');

        $orderGoods = OrderGoods::whereIn('order_id', $orderIds)
            ->field('goods_id, goods_name, goods_name, goods_price, goods_info, order_id, goods_num')
            ->select()->toArray();

        $arr = [];
        foreach ($orderGoods as $item) {
            $goods = Db::name('goods')->where(['id' => $item['goods_id']])->find();
            $item['description'] = $goods['description'] ?? '';
            $item['image'] = $goods['image']  ?? '';
            $arr[$item['order_id']][] = $item;
        }

        foreach ($order['data'] as $key => $item) {
            $order['data'][$key]['goods'] = $arr[$item['id']] ?? [];
        }
        $this->_success('查询成功', $order);

    }

    //订单详情
    public function orderDetail()
    {
        $userId = $this->user_info['id'];
        $orderId = $this->request->get('order_id');
        $data['order_id'] = $orderId;
        $result = $this->validate($data,'app\api\validate\FeiHong.detail');
        if($result !== true){
            $this->_error($result);
        }


        $order = \app\api\model\Order::where(['id' => $orderId, 'user_id' => $userId])->find();
        if (!$order) {
            $this->_error('订单不存在');
        }
        $row['address']['latitude'] = $order['latitude'];
        $row['address']['name'] = $order['consignee'];
        $row['address']['mobile'] = $order['mobile'];
        $row['address']['address'] = $order['address'].($order['address_detail'] ?: '');

        $row['orderMsg']['order_sn'] = $order['order_sn'];  //订单编号
        $row['orderMsg']['order_status'] = $order['order_status'];  //订单状态
        $row['orderMsg']['is_recovery'] = $order['is_recovery'];  //是否需要旧瓶回收 0否1是
        $row['orderMsg']['create_time'] = $order['create_time'] ;  //下单时间
        $row['orderMsg']['user_remark'] = $order['user_remark'] ;  //订单备注
        $row['orderMsg']['pay_time'] = $order['pay_time'] ?: '';  //支付时间
        $row['orderMsg']['bottle_deposit'] = $order['bottle_deposit'];  //钢瓶押金
        $row['orderMsg']['bottle_amount'] = $order['bottle_amount'];  //气价
        $row['orderMsg']['order_amount'] = $order['order_amount'];  //实际付款金额
        $row['orderMsg']['floor_amount'] = $order['floor_amount'];  //楼层费
        $row['orderMsg']['displace_or_add'] = $order['displace_or_add'];  //1押瓶置换2新增押瓶
        $row['orderMsg']['bottle_send'] = json_decode($order['bottle_send'], true);
        $row['orderMsg']['bottle_put'] = json_decode($order['bottle_put'], true);

        $site = Db::name('bottle_site')->where(['id' => $order['site_id']])->find();
        $row['siteMsg']['address'] = $site['address'];
        $row['siteMsg']['name'] = $site['name'];
        $row['siteMsg']['head_mobile'] = $site['head_mobile'];
        $row['siteMsg']['latitude'] = $site['latitude'];


        $additionalPrice = 0;
//        $goods = OrderGoods::where(['order_id' => $orderId])->select();
        $goods = json_decode($order['goods_id'],true);
        // var_dump($goods);
        foreach ($goods as $key => $item) {
            $row['goods'][$key]['goods_name'] = $item['goods_name'];
            $row['goods'][$key]['goods_price'] = $item['goods_price'];
            $row['goods'][$key]['goods_num'] = $item['goods_number'];
            $rows = Db::name('goods')->where(['id' => $item['goods_id']])->find();
            $row['goods'][$key]['image'] = $item['goods_image'] ?? '';
            $row['goods'][$key]['description'] = $rows['description'] ?? '';

            //计算押金，租金
            if (isset($rows['type']) && $rows['type'] == 2) {
                //增购商品价
                $additionalPrice += $item['goods_price']*$item['goods_number'];
            }
        }
        $row['orderMsg']['additionalPrice'] = $additionalPrice;  //添加商品
        $row['orderMsg']['rent'] = $order['settle_bottle_rent'];  //钢瓶使用费
        $this->_success('查询成功', $row);
    }


    //我的订单数量
    public function orderNum()
    {
        $userId = $this->user_info['id'];
        $orderCount = \app\api\model\Order::where(['user_id' => $userId, 'del' => 0])
            ->count('id');
        $this->_success('查询成功', $orderCount);
    }

    //图片上传
    public function uploadHead()
    {
        try {
            $file = $this->request->file('file');
            if (empty($file)) {
                throw new Exception('请选择上传的文件');
            }
            $info = $file->validate(['ext' => 'jpg,jpeg,png'])->move(ROOT_PATH.'/uploads');

            if($info){
                //获取上传文件的url
//                $image_url = str_replace('\\', '/', ROOT_PATH).'/uploads/'.str_replace("\\","/",$info->getSaveName());
                $image_url = '/uploads/'.str_replace("\\","/",$info->getSaveName());
                $image_url = UrlServer::getFileUrl($image_url);
            }else{
                //上传失败获取错误信息
                throw new Exception('上传失败');
            }
            $this->_success('上传成功', $image_url);
        }catch (Exception $e) {
            $this->_error($e->getMessage());
        }


    }

    //用户资料修改
    public function userInfos()
    {
        try {
            Db::startTrans();
            $data = Request::post();
            //验证
            $result = $this->validate($data,'app\api\validate\FeiHong.info');
            if($result !== true){
                $this->_error($result);
            }
            $userId = $this->user_info['id'];
            $user = User::where(['id' => $userId])->find();
            $model = $user->save($data);
            if (!$model) {
                throw new Exception('修改失败');
            }
            DB::commit();
            $this->_success('修改成功');
        }catch (Exception $e) {
            DB::rollback();
            $this->_error($e->getMessage());
        }

    }


    //确认下单
    public function smOrder()
    {
        Db::startTrans();
        try {
            $data = Request::post();
            $user = $this->user_info;
            $result = $this->validate($data,'app\api\validate\FeiHong.order');
            if($result !== true){
                $this->_error($result);
            }
            $displaceOrAdd = $data['displace_or_add'] ?? '';  //订气类型

            //1.判断是否在配送范围
            if (in_array($user['type'], [1, 2])) {
                $where = ' type = 2 ';
            } else {
                $where = ' type = 1 ';
            }
            $user = Db::name('user')->where(['id' => $user['id']])->field('bottle_num, id, latitude, address, type, site_id, discount_amount')->find();
            $orderList = Cache::get($user['id']);
            $goods = json_decode($orderList, true); //下单的商品
            // var_dump($goods);
            //3.押瓶充气金额计算 气价+楼层费  主商品才有楼层费
            $payInfo = $this->payInfo($displaceOrAdd); //押金，租金付款信息,气价，楼费
            // var_dump($payInfo);die;
            //无押瓶的客户只能新增押瓶
            if ($displaceOrAdd == 1 && $payInfo['goodsNum'] > $user['bottle_num']) {
                $this->_error('置换大于我的押瓶数');
            }
            if (empty($user['address'])) {
                throw new Exception('用户未选择地址');
            }
            $bSite = Db::name('bottle_site')->where($where)->where(['del' => 0])->select();
            $flagNums = count($bSite); //用来判断是否全部站点匹配不上
            if (!$bSite) {
                throw new Exception('不在配送范围内,请拨打咨询电话订气');
            }
            $i = 0;
            $bSiteId = 0;
            foreach ($bSite as $bItem) {
                $bLat = explode(',', $bItem['latitude2']);
                $uLat = explode(',', $user['latitude']);
                $blatCount = count($bLat);
                $uLatCount = count($uLat);

                if ($blatCount < 2 || $uLatCount < 2) {
                    throw new Exception('坐标格式不正确');
                }
                $distance = distance($bLat[0] ,$bLat[1], $uLat[0], $uLat[1] );

                if ($distance > $bItem['delivery_range_meter']) {
                    $i++;
                } else {
                    $bSiteId = $bItem['id'];
                }
            }
            if ($i == $flagNums) {
                throw new Exception('不在配送范围内,请拨打咨询电话订气');
            }
            if (!$goods) {
                throw new Exception('请先下单');
            }
            //4.入订单表 order order_goods
            //减去优惠金额
            if ($user['discount_amount']) {
                $payInfo['price'] = $payInfo['price'] - $user['discount_amount'];
            }
            $order = new \app\api\model\Order();
            $data['order_sn'] = createSn('order', 'order_sn');
            $data['user_id'] = $user['id'];
            $data['site_id'] = $bSiteId;
            $data['delivery_type'] = 1;
            $data['floor_amount'] = bcmul($payInfo['floorCost'], $payInfo['goodsNum'], 2);
            $data['latitude'] = $user['latitude'];
            $data['bottle_amount'] = $payInfo['price'];
            $data['bottle_num'] = $payInfo['goodsNum'];
            $data['new_bottle_num'] = $displaceOrAdd == 2 ? $payInfo['newNum'] : 0;
            $data['bottle_deposit'] = $payInfo['deposit'];
            $data['settle_bottle_rent'] = $payInfo['rent'];
            $data['create_time'] = date('Y-m-d H:i:s', time());
            $data['order_amount'] = bcadd(bcadd(bcadd(bcadd($payInfo['deposit'], $payInfo['rent'], 2), $payInfo['price'], 2), $data['floor_amount'], 2), $payInfo['additionalPrice'], 2) ;
            $data['bottle_send'] = isset($data['bottle_send']) ? json_encode($data['bottle_send'], 256) : '';
            $data['bottle_put'] = isset($data['bottle_put']) ? json_encode($data['bottle_put'], 256) : '';
            $goodsArr = [];
            $goodsData = [];
            foreach ($goods as $key => $item) {
                $row = Db::name('goods')->where(['id' => $item['id']])->find();
                $goods_price = $row['price'];
                $num = $item['num'];
                $goodsArr[$key]['goods_id'] = $item['id'];
                $goodsArr[$key]['goods_name'] = $item['name'];
                $goodsArr[$key]['goods_number'] = $item['num'];
                $goodsArr[$key]['goods_type'] = $row['type'];
                $goodsArr[$key]['goods_price'] = $row['price'];
                $goodsArr[$key]['goods_image'] = $row['image'];
                $goodsData[$key]['goods_id'] = $item['id'];
                $goodsData[$key]['goods_price'] = $goods_price;
                $goodsData[$key]['goods_name'] = $item['name'];
                $goodsData[$key]['goods_num'] = $num;
                $goodsData[$key]['total_price'] = bcmul($goods_price, $num, 2);
                $goodsData[$key]['total_pay_price'] = $item['name'];
            }

            $data['goods_id'] = json_encode($goodsArr, 256);
            $result = $order->insertGetId($data);
            if ($result) {
                //绑定用户站点
                if (!$user['site_id']) {
                    Db::name('user')->where(['id' => $this->user_info['id']])->update(['site_id' => $data['site_id']]);
                }
                foreach ($goodsData as &$v) {
                    $v['order_id'] = $result;
                }
                $orderGoods = new OrderGoods();
                $goodsResult = $orderGoods->insertAll($goodsData);
                if (!$goodsResult) {
                    throw new Exception('提交订单失败');
                }
                //清除购物车信息
                Cache::rm($user['id']);
            }
            $data['goods'] = $goodsData;
            $data['order_id'] = $result;
            Db::commit();
            $this->_success('下单成功', $data);
        }catch (Exception $e) {
            Db::rollback();
            $this->_error($e->getMessage());
        }

    }

    //付款信息
    public function payMessage()
    {
        $displaceOrAdd = $this->request->get('displace_or_add', '');
        $payInfo = $this->payInfo($displaceOrAdd);
//        $payInfo['bottle_num'] = Db::name('user')->where(['id' => $this->user_info['id']])->value('bottle_num');
        $payInfo['bottle_num'] = Db::name('bottle')->where(['user_id' => $this->user_info['id']])->count();
        $this->_success('查询成功', $payInfo);
    }
    //提交或者修改合同管理
    public function management()
    {
        $data = Request::post();
        $user = $this->user_info;
        $userId = $user['id'];
        $result = $this->validate($data,'app\api\validate\FeiHong.management');
        if($result !== true){
            $this->_error($result);
        }
        $data['user_id'] = $userId;
        $data['create_time'] = date('Y-m-d H:i:s', time());

        $model = Management::where(['user_id' =>$userId])->find();
        if (!$model) {
            $model = new Management();
        }
        $result = $model->save($data);
        if ($result) {
            $this->_success('提交成功');
        }
        $this->_error('提交失败');
    }

    //查看合同管理
    public function managementList():object
    {
        $user = $this->user_info;
        $userId = $user['id'];
        return Management::where(['user_id' =>$userId])->find();
    }

    private function getAddress()
    {
        $data = Request::post();
        //验证

        $result = $this->validate($data,'app\api\validate\FeiHong.res');
        if($result !== true){
            $this->_error($result);
        }

        if ($data['if_elevator'] == 0 && empty($data['floor'])) {
            $this->_error('请填写楼层');
        }

//        $data['address'] = $data['address'].$data['address_detail'];
//        unset($data['address_detail']);
        $data['open_time'] = date('Y-m-d H:i:s', time());
        $data['create_time'] = date('Y-m-d H:i:s', time());
        $data['reg_time'] = date('Y-m-d H:i:s', time());

        $data['if_open'] = 1; //站点ID？
        return $data;
    }

    //删除购物车的其中一个商品
    public function delCart()
    {
        $goodsId = $this->request->post('goods_id');
        $user = $this->user_info;
        $orderList = Cache::get($user['id']);
        $goods = json_decode($orderList, true); //下单的商品

        $arr = [];
        if ($goods) {
            foreach ($goods as $item) {
                if ($item['id'] != $goodsId) {
                    $arr[] = $item;
                }
            }
        }
        Cache::rm($user['id']);
        Cache::set($user['id'], json_encode($arr, 256));
        $this->_success('删除购车商品成功', $arr);
    }

    //调起微信支付
    public function payMoney()
    {
        $orderId = $this->request->post('order_id');
        $userId = $this->user_info['id'];
        $auth = Db::name('user_auth')->where(['user_id' => $userId, 'type' => 0])->find();
        $order_source = $auth['client'] ?? 1; // 小程序
        $mobile = Db::name('user')->where(['id' => $userId])->value('mobile');
        $vcCode = Cache::get($mobile.'test9999'); //短信验证码
        if ($vcCode == 999999) {
            $time = time();
            $order_model = new Order();
            $order = $order_model
                ->with('order_goods')
                ->where('id',$orderId)
                ->find();
            //增加会员消费累计额度
            $user = \app\common\model\User::get($order['user_id']);
            $user->total_order_amount = ['inc', $order['order_amount']];
            $user->save();

            $order->pay_status = Pay::ISPAID;
            $order->pay_time = date('Y-m-d H:i:s', $time);
            $order->order_status = Order::STATUS_WAIT_DELIVERY;
            $order->order_source = 2; //手动下单
            $order->save();

            //处理钢瓶表
            Db::name('bottle_rent_log')->where(['user_id' => $order['user_id']])->update(['if_pay' => 1, 'pay_time' => date('Y-m-d H:i:s')]);
            OrderGoodsLogic::decStock($order['order_goods']);


            //订单日志
            OrderLogLogic::record(
                OrderLog::TYPE_USER,
                OrderLog::USER_PAID_ORDER,
                $order['id'],
                $user['id'],
                OrderLog::USER_PAID_ORDER
            );

            //发送到配送员通知
            Db::name('order_mes')
                ->insert(['order_id' => $order['id'], 'site_id' => $order['site_id'], 'create_time' => date('Y-m-d H:i:s')]);
//           $driver = Db::name('driver')->where(['site_id' => $order['site_id'] ])->field('id')->select();
//           Hook::listen('notice', [
//               'user_id' => $driver,
//               'order_id' => $order['id'],
//               'scene' => NoticeSetting::ORDER_PAY_NOTICE,
//           ]);
            $this->_success('支付成功');
        }
        $order = \app\api\model\Order::where(['user_id' => $userId, 'id' => $orderId, 'order_status' => 0])->find();
        $result = WeChatPayServer::unifiedOrder('order', $order, $order_source);

        $mes = $result['mes'] ?? '';
        if ($mes) {
            $wechat_config = WeChatPayServer::getWeChatConfig($order, $order_source);
            $this->_error($mes, $wechat_config);
        }
        $this->_success('查询成功', $result);
    }

    //模拟支付接口
    public function payment()
    {
        $orderId = $this->request->post('order_id');
        $userId = $this->user_info['id'];
        $order = \app\api\model\Order::where(['user_id' => $userId, 'id' => $orderId])->update(['order_status' => 1]);
        if ($order) {
            //
            $data['order_id'] = $orderId;
            $this->_success('支付成功', $data);
        }
    }

    //付款信息计算，数据展示

    private function payInfo($displaceOrAdd = 0)
    {
        $user = $this->user_info;
        $orderList = Cache::get($user['id']);
        $user = Db::name('user')->where(['id' => $user['id']])->find(); //动态获取避免修改资料读取以前缓存
        //根据商品去计算
        /**
         * 钢瓶押金 首次购买需要付钢瓶押金，下单大于钢瓶押金的计算大于那个
         * 钢瓶使用费
         * 气价
         * 添加商品？
         * 实际付款金额
         */

        $goods = json_decode($orderList, true); //下单的商品
        $deposit = 0; //押金
        $goodsNum = 0; //主商品数量
        $price = 0; //所有商品价格 = 气价？
        $floorCost = 0; //楼层费用
        $rent = 0;
        $additionalPrice = 0;
        //主商品需要押瓶
        if ($goods) {
            foreach ($goods as $item) {
                //计算押金，租金
                if ($item['type'] == 1) {
                    $goodsNum += $item['num'];
                    $price += $item['price']; //气价
                } else {
                    //增购商品价
                    $additionalPrice += $item['price'];
                }

            }

            if ($displaceOrAdd == 2) {
                //押瓶新增计算
                //需要付押瓶的钱
                $deposit = bcmul($goodsNum, $this->getConfig('pay', 'bottle_deposit'), 2);
                // 如果用户设置了押金和租金则优先
                if( isset($user['bottle_deposit']) ){
                    //$deposit = round($user['bottle_deposit'],2);
                    $deposit = bcmul($goodsNum, round($user['bottle_deposit'],2), 2);
                }
            }
            if ($user['if_elevator'] == 0 && $user['floor'] > 1) { //步梯
                if ($user['floor'] == 2) {
                    $floorCost = $this->getConfig('pay', 'floor');
                }
                if ($user['floor'] > 2) {
                    $floorNum = $user['floor'] - 2;
                    $floorCost = $floorNum * $this->getConfig('pay', 'floor') + $this->getConfig('pay', 'floor');
                }

            }
            //租瓶押金结算记录表
            $rent = Db::name('bottle_rent_log')->where(['user_id' => $user['id'], 'if_pay' => 0])->sum('pay_amount');
//            //调用配置表租金叠加欠费
//            $bottle_rent = $this->getConfig('pay', 'bottle_rent');
//            $rent+=$bottle_rent;
        }

        if( isset($user['bottle_rent']) ){
            $rent = round($user['bottle_rent'],2);
        }
        return ['deposit' => $deposit,  'rent'=> $rent, 'price' => round($price, 2), 'floorCost' => $floorCost, 'newNum' => $goodsNum
            , 'goodsNum' => $goodsNum, 'additionalPrice' => $additionalPrice, 'discount_amount' => $user['discount_amount']];
    }

    public function getConfig($type, $name)
    {
        return Db::name('config')->where(['type' => $type, 'name' => $name])->value('value');
    }

    private function getUser($mobile)
    {
        return User::where(['mobile' => $mobile])->find();
    }
    private function checkMobile($value)
    {
        //检查手机号是否已存在
        $user = Db::name('user')
            ->where('mobile', '=', $value)
            ->find();

        if ($user) {
            return false;
        }

        return true;
    }
    //半年租金定时器生成
    public function rent()
    {
        //租金每半年生成一次，
        $month = date('n'); // 当前月份
        $day = date('d'); // 当前多少号
        $type = date('Y');

        if (($month  == 7 && $day == 1) || ($month  == 1 && $day == 1)) {

            $bottlePayAmount = Db::name('bottle_rent_log')->where(['if_pay' => 0])
                ->field('pay_amount, user_id, bottle_code, create_time')->select(); //查询所有用户欠费

            $user = Db::name('user')->column('bottle_num', 'id');
            //需要知道该用户支付时间月份跟半年度相减
            $arr = [];
            $i = 0;
            foreach ($bottlePayAmount as $item) {
                $bottleNum = $user[$item['user_id']] ?? 0; //每个用户的押瓶数量 PS:用户押瓶数量下单回调计算加上
                //判断用户的押瓶数以及原先bottle_rent_log 所押的瓶计算方式不同
                $order = Db::name('order')->where(['user_id' => $item['user_id'], 'displace_or_add' => 2])
                    ->where("DATE_FORMAT(pay_time, '%Y%m') > DATE_FORMAT('{$item['create_time']}', '%Y%m')")
                    ->field('pay_time, bottle_num')
                    ->select(); // 该用户在上一季度生成租金之后所有支付成功的订单

                $bottleCode = Db::name('bottle')->where(['user_id' => $item['user_id']])->field('code, createtime')->select();
                $price = 0;
                if ($order) {
                    foreach ($order as $v) {
                        //每个订单的支付时间
                        if ($month == 1) {
                            $type .='下半年租金计算';
                            $nums = 12 - date('n', strtotime($v['pay_time']));  //当前7或者1月份减去支付月份
                        } else {
                            $type .='上半年租金计算';
                            $nums = 6 - date('n', strtotime($v['pay_time']));
                        }
                        $liang = $v['bottle_num'] * $nums; // 订气的数量
                        $sum = bcmul($liang,$this->getConfig('pay', 'bottle_rent'), 2);
                        $price += (float)$sum;
                    }
                }

                $rent = bcadd(bcmul($bottleNum,$this->getConfig('pay', 'bottle_rent'), 2), $item['pay_amount'], 2);
                $amount = $price + (float)$rent; // 租金
                $arr[$i]['user_id'] = $item['user_id'];
                $arr[$i]['type'] = $type;
                $co = [];
                $j = 0;
                foreach ($bottleCode as $code) {
                    $co[]['bottle_code'] = $code['bottle_code'];
                    $co[]['time'] = date('Y-m-01', strtotime($code['createtime']));
                    $j++;
                }
                $arr[$i]['bottle_code'] = json_encode($co, 256);
                $arr[$i]['pay_amount'] = $amount;
                $arr[$i]['if_pay'] = 0;
                $arr[$i]['pay_time'] = 0;
                $arr[$i]['create_time'] = date('Y-m-d H:i:s');
                $i++;
            }
            Db::name('bottle_rent_log')->insertAll($arr);
        }

    }

    public function driverMes()
    {
        try {
            $res = Db::name('order_mes')->where(['status' => 0])->select();
            if ($res) {
                foreach ($res as $item) {
                    $driver = Db::name('driver')->where(['site_id' => $item['site_id']])->field('id')->select();
                    Hook::listen('notice', [
                        'user_id' => $driver,
                        'order_id' => $item['order_id'],
                        'scene' => NoticeSetting::ORDER_PAY_NOTICE,
                    ]);
                }
            }
            echo '执行成功触发'.count($res).'数据';
//             $this->_success();
//             return '执行成功触发'.count($res).'数据';
        }catch(Exception $e) {
            echo '报错:'.$e->getMessage();
            Log::write(date('Y-m-d H:i:s').'时间，报错：'.$e->getMessage());
        }
    }

    //用户协议授权
    public function isAgreement()
    {
        $user = Db::name('user')->where(['id' => $this->user_info['id']])->find();
        if (empty($user['is_agreement'])) {
            $this->_error('用户未授权用户协议');
        }
        $this->_success('已授权', ['is_agreement' => $user['is_agreement']]);
    }

    //用户更改授权变更状态
    public function smAgreement()
    {
        Db::name('user')->where(['id' => $this->user_info['id']])
            ->update(['is_agreement' => 1]);
        $this->_success('用户授权成功');
    }

    //获取wchat
    public function getWeChatToken()
    {
        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx45afad0e910405ad&secret=cd1ac9f22a61bc95476f092c5acf48f0';
        $data = file_get_contents($url);
        if ($data) {
            $data = json_decode($data,true);
            $this->_success('查询成功', $data);
        }
        $this->_error('暂无数据');
    }
    //获取手机
    public function getWeChatIphone()
    {
        $access_token= Request::get('access_token');
        $code = Request::get('code');
//
//       $url = 'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token='.$access_token;
        $postData = json_encode(['code'=>$code]);
//        $header = array(
//            'Content-Type: application/x-www-form-urlencoded'
//        );
        $url                   = 'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token='.$access_token;
        $curl_return_data      = $this->postCurl($url,$postData , true);
        $curl_return_ary       =@json_decode($curl_return_data, true);
        if(!$curl_return_ary || empty($curl_return_ary['phone_info']))
        {
            $this->_error('getPhoneNumber 获取失败');
        }

        if ($curl_return_ary) {
            $this->_success('查询成功', $curl_return_ary);
        }
        $this->_error('暂无数据');
    }

    /**
     * curl post json 请求
     * */
    function postCurl($url,$data,$json =false){

        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        if (!empty($data)) {
            if($json && is_array($data)){
                $data = json_encode( $data );
            }
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            if($json){ //发送JSON数据
                curl_setopt($curl, CURLOPT_HEADER, 0);
                curl_setopt($curl, CURLOPT_HTTPHEADER,
                    array('Content-Type: application/json; charset=utf-8', 'Content-Length:' . strlen($data)));}
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $res = curl_exec($curl);
//        var_dump($res);
        $errorno = curl_errno($curl);
        if ($errorno) {
            return array('errorno' => false, 'errmsg' => $errorno);
        }
        curl_close($curl);
        return $res;
    }
}